package com.example.shirodemo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.example.shirodemo.constant.HttpCode;
import com.example.shirodemo.constant.StatusCode;
import com.example.shirodemo.controller.vo.ApiListVo;
import com.example.shirodemo.controller.vo.MenuVo;
import com.example.shirodemo.controller.vo.RoleMenuVo;
import com.example.shirodemo.controller.vo.RolePermissionVo;
import com.example.shirodemo.controller.vo.UserAdminVo;
import com.example.shirodemo.controller.vo.UserRoleVo;
import com.example.shirodemo.dto.ResponseResult;
import com.example.shirodemo.dto.ResponseResultPage;
import com.example.shirodemo.entity.SMenu;
import com.example.shirodemo.entity.SPermission;
import com.example.shirodemo.entity.SRole;
import com.example.shirodemo.entity.SRolePermission;
import com.example.shirodemo.mapper.SMenuMapper;
import com.example.shirodemo.mapper.SPermissionMapper;
import com.example.shirodemo.mapper.SRoleMapper;
import com.example.shirodemo.mapper.SRoleMenuMapper;
import com.example.shirodemo.mapper.SRolePermissionMapper;
import com.example.shirodemo.mapper.SUserMapper;
import com.example.shirodemo.service.AdminService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.service.ApiListing;
import springfox.documentation.service.Documentation;
import springfox.documentation.service.Operation;
import springfox.documentation.spring.web.DocumentationCache;

/**
 * @Author 绫小路
 * @Date 2021/1/11
 */
@Service
public class AdminServiceImpl implements AdminService {

  @Autowired
  private SMenuMapper sMenuMapper;
  @Autowired
  private SRoleMenuMapper sRoleMenuMapper;
  @Autowired
  private SUserMapper sUserMapper;
  @Autowired
  private SRoleMapper sRoleMapper;
  @Autowired
  private DocumentationCache documentationCache;
  @Autowired
  private SPermissionMapper sPermissionMapper;
  @Autowired
  private SRolePermissionMapper sRolePermissionMapper;


  @Override
  public ResponseResultPage getRoleLists(String search, int page, int limit) {
    Page pages = PageHelper.startPage(page, limit);
    List<SRole> result = sRoleMapper.getRoleLists(search);
    return new ResponseResultPage(HttpCode.OK, page, limit, pages.getTotal(), result);
  }

  @Override
  public ResponseResult addRole(String name, String description) {
    SRole s = sRoleMapper.get(name, 1);
    if (s != null && s.getStatus() == StatusCode.VALID) {
      return new ResponseResult(HttpCode.FAIL, "已经存在的角色名: " + name);
    }
    SRole role = new SRole();
    role.setName(name);
    role.setDescription(description);
    role.setCreateTime(new Date());
    role.setStatus(StatusCode.VALID);
    sRoleMapper.insertSelective(role);
    return new ResponseResult(HttpCode.OK, "添加成功！");
  }

  @Override
  public ResponseResult deleteRole(String name) {
    sRoleMapper.delete(name);
    return new ResponseResult(HttpCode.OK, "删除角色成功！");
  }

  @Override
  public ResponseResult editRole(Integer id, String name, String description) {
    sRoleMapper.update(id, name, description);
    return new ResponseResult(HttpCode.OK, "修改成功！");
  }

  @Override
  public ResponseResult getAllMenu() {
    List<SMenu> list = sMenuMapper.getAll();
    return new ResponseResult(HttpCode.OK, list);
  }

  @Override
  public SMenu menuInfo(Integer id) {
    return sMenuMapper.selectByPrimaryKey(id);
  }

  @Override
  public ResponseResult updateMenu(MenuVo menuVo) {
    SMenu menu = BeanUtil.copyProperties(menuVo, SMenu.class);
    menu.setUpdateTime(new Date());
    sMenuMapper.updateByPrimaryKeySelective(menu);
    return new ResponseResult(HttpCode.OK, "更新成功！");
  }

  @Override
  public ResponseResult addMenu(MenuVo menuVo) {
    SMenu menu = BeanUtil.copyProperties(menuVo, SMenu.class);
    menu.setCreateTime(new Date());
    sMenuMapper.insertSelective(menu);
    return new ResponseResult(HttpCode.OK, "添加成功！");
  }

  @Override
  public ResponseResult deleteMenu(Integer id) {
    SMenu menu=new SMenu();
    menu.setId(id);
    menu.setStatus(0);
    sMenuMapper.updateByPrimaryKeySelective(menu);
    return new ResponseResult(HttpCode.OK,"删除成功！");
  }

  @Override
  public ResponseResult roleMenu(int roleId) {
    List<RoleMenuVo> list = sMenuMapper.getRoleMenu(roleId);
    return new ResponseResult(HttpCode.OK, list);
  }

  @Transactional
  @Override
  public ResponseResult roleAddMenu(Integer roleId, String ids) {
    sRoleMenuMapper.deleteAll(roleId);
    if (StrUtil.isBlank(ids)) {
      return new ResponseResult(HttpCode.OK, "保存成功！");
    }
    String[] idss = ids.split(",");
    List<Integer> is = new ArrayList<>();
    for (String v : idss) {
      is.add(Integer.valueOf(v.trim()));
    }
    sRoleMenuMapper.addAll(roleId, is);
    return new ResponseResult(HttpCode.OK, "保存成功！");
  }

  @Override
  public ResponseResultPage getUserList(Integer page, Integer limit, String search) {
    Page pages = PageHelper.startPage(page, limit);
    List<UserAdminVo> result = sUserMapper.getList(search);
    return new ResponseResultPage(HttpCode.OK, page, limit, pages.getTotal(), result);
  }

  @Override
  public ResponseResult getUserRoleVo(Integer userId) {
    List<UserRoleVo> vos = sUserMapper.getUserRole(userId);
    return new ResponseResult(HttpCode.OK, vos);
  }

  @Transactional
  @Override
  public ResponseResult updateUserRole(Integer userId, String ids) {
    sUserMapper.deleteUserRole(userId);
    if (StrUtil.isBlank(ids)) {
      return new ResponseResult(HttpCode.OK, "更新角色成功！");
    }
    String[] is = ids.split(",");
    List<Integer> roleIds = new ArrayList<>();
    for (String i : is) {
      roleIds.add(Integer.valueOf(i.trim()));
    }
    sUserMapper.addUserRole(userId, roleIds);
    return new ResponseResult(HttpCode.OK, "更新角色成功！");
  }

  @Override
  public ResponseResult getSwaggerApiList() {
    Documentation documentation = documentationCache.documentationByGroup("default");
    if (documentation == null) {
      return new ResponseResult(HttpCode.OK);
    }
    Map<String, List<ApiListing>> listMap = documentation.getApiListings();
    System.out.println(listMap.toString());
    List<ApiListVo> apiListVos = new ArrayList<>();
    for (Map.Entry<String, List<ApiListing>> entry : listMap.entrySet()) {
      entry.getValue().forEach(api -> {
        System.out.println(api.getApis());
        api.getApis().forEach(info -> {
          ApiListVo vo = new ApiListVo();
          vo.setUrl(info.getPath());
          for (Operation o : info.getOperations()) {
            vo.setMethod(o.getMethod().name());
            vo.setSummary(o.getSummary());
          }
          apiListVos.add(vo);
        });
      });
    }
    List<ApiListVo> result = new ArrayList<>(apiListVos.size());
    for (ApiListVo v : apiListVos) {
      v.setHas(sPermissionMapper.hasUrl(v.getUrl(), v.getMethod()));
      result.add(v);
    }

    StringBuffer sql = new StringBuffer();
    //排序
    Collections.sort(result, new Comparator<ApiListVo>() {
      @Override
      public int compare(ApiListVo o1, ApiListVo o2) {
        //按字典顺序比较两个字符串，忽略大小写
        if (o1.getUrl().compareToIgnoreCase(o2.getUrl()) < 0) {
          return -1;
        }
        return 1;
      }
    });
    //生成sql
    for (ApiListVo v : result) {
      if (v.getHas() == 0) {
        sql.append(String.format("insert into s_permission(url,method,description,create_time) values ('%s','%s','%s',now());\n",
            v.getUrl(),
            v.getMethod(),
            v.getSummary()
        ));
      }
    }
    System.out.println(sql);
    return new ResponseResult(HttpCode.OK, apiListVos);
  }

  @Override
  public ResponseResultPage getPermissionList(String search, int page, int limit) {
    Page p = PageHelper.startPage(page, limit);
    List<SPermission> result = sPermissionMapper.getAllPermission(search);
    return new ResponseResultPage(HttpCode.OK, page, limit, p.getTotal(), result);
  }

  @Override
  public ResponseResult addPermission(String url, String method, String description) {
    int has = sPermissionMapper.hasUrl(url, method);
    if (has > 0) {
      return new ResponseResult(HttpCode.FAIL, "已经存在的URL");
    }
    SPermission permission = new SPermission();
    permission.setCreateTime(new Date());
    permission.setUrl(url);
    permission.setMethod(method);
    permission.setDescription(description);
    sPermissionMapper.insertSelective(permission);
    //清除缓存
    PermissionServiceImpl.cachePermissionRole.clear();
    return new ResponseResult(HttpCode.OK, "添加成功！");
  }

  @Override
  public ResponseResult deletePermission(Integer id) {
    sPermissionMapper.deleteByPrimaryKey(id);
    //清除缓存
    PermissionServiceImpl.cachePermissionRole.clear();
    return new ResponseResult(HttpCode.OK, "删除成功！");
  }

  @Override
  public ResponseResult updatePermission(Integer id, String url, String method, String description) {
    int has = sPermissionMapper.hasUrl(url, method);
    if (has > 1) {//是否存在重复
      return new ResponseResult(HttpCode.FAIL, "已经存在的URL");
    }

    SPermission permission = new SPermission();
    permission.setId(id);
    permission.setUpdateTime(new Date());
    permission.setUrl(url);
    permission.setMethod(method);
    permission.setDescription(description);
    sPermissionMapper.updateByPrimaryKeySelective(permission);
    //清除缓存
    PermissionServiceImpl.cachePermissionRole.clear();
    return new ResponseResult(HttpCode.OK, "更新成功！");
  }

  @Override
  public ResponseResultPage getRolePermission(Integer roleId, String search, int page, int limit) {
    Page p = PageHelper.startPage(page, limit);
    List<RolePermissionVo> result = sRolePermissionMapper.get(roleId, search);
    return new ResponseResultPage(HttpCode.OK, page, limit, p.getTotal(), result);
  }

  @Transactional
  @Override
  public ResponseResult updateRolePermission(Integer roleId, String ids, Boolean checked) {
    //清除缓存
    PermissionServiceImpl.cachePermissionRole.clear();
    //1、为空的时候
    if (StrUtil.isBlank(ids)) {
      sRolePermissionMapper.deleteAll(roleId);
      return new ResponseResult(HttpCode.OK, "更新成功！");
    }

    String[] is = ids.split(",");

    //2、只有一个的时候，只针对一个更新
    if (is.length == 1) {
      int count = sRolePermissionMapper.has(roleId, Integer.valueOf(is[0].trim()));
      if (count == 0) {
        if (checked) {
          SRolePermission permission = new SRolePermission();
          permission.setRoleId(roleId);
          permission.setPermissionId(Integer.valueOf(is[0].trim()));
          sRolePermissionMapper.insertSelective(permission);
        }
      } else {
        if (!checked) {
          sRolePermissionMapper.delete(roleId, Integer.valueOf(is[0].trim()));
        }
      }
      return new ResponseResult(HttpCode.OK, "更新成功！");
    }

    //3、多个的时候
    sRolePermissionMapper.deleteAll(roleId);
    for (String id : is) {
      SRolePermission permission = new SRolePermission();
      permission.setRoleId(roleId);
      permission.setPermissionId(Integer.valueOf(id.trim()));
      sRolePermissionMapper.insertSelective(permission);
    }
    return new ResponseResult(HttpCode.OK, "更新成功！");
  }
}
